import base64
import pickle

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
# Create your views here.
from carts.serializers import CartSerialziers, SKUSerialziers, CartDeleteSerialziers, CartSelectedSerialziers
from django_redis import get_redis_connection

from goods.models import SKU


class CartsView(APIView):
    def perform_authentication(self, request):
        # 在调用方法之前会获取用户对象，所以重写
        pass

    def post(self, request):
        # 1、获取前端数据传递商品数据
        data = request.data
        # 前端传递数据　token　商品ｉｄ　数量　选中状态
        ser = CartSerialziers(data=data)
        ser.is_valid()

        sku_id = ser.validated_data['sku_id']
        count = ser.validated_data['count']
        selected = ser.validated_data['selected']
        try:
            # 判断用户是否登录
            user = request.user
        except:
            user = None
        if user is not None:
            conn = get_redis_connection('cart')
            conn.hincrby('cart_%s' % user.id, sku_id, count)
            if selected:
                conn.sadd('cart_selected_%s' % user.id, sku_id)
            return Response("OK")
        else:
            # 先判断是否有cookie存在
            cart_cookie = request.COOKIES.get('cart_cookie')
            if cart_cookie:
                cart = pickle.loads(base64.b64decode(cart_cookie))
            else:
                # 没有cookie定义一个字典
                cart = {}
        # 有cookie获取cookie值增加
        sku_dict = cart.get(sku_id)
        if sku_dict:
            count += int(sku_dict.get['count'])
        cart[sku_id] = {
            'count': count,
            'selected': selected
        }
        # 将新的字典数据写入cookie
        cart_cookie = base64.b64encode(pickle.dumps(cart)).decode()
        # 设置cookie
        response = Response('ok')
        response.set_cookie('cart_cookie', cart_cookie, max_age=60 * 60 * 24 * 7)
        return response

    def get(self, request):
        # 获取前端传递对象
        try:
            user = request.user
        except:
            user = None
        # 判断用户是否登录
        if user:
            # 用户登录 根据用户id获取redis存储数据
            conn = get_redis_connection('cart')
            sku_id_count = conn.hgetall('cart_%s' % user.id)
            sku_selected = conn.smembers('cart_selected_%s' % user.id)
            # 拼接成字典
            cart = {}
            for sku_id, count in sku_id_count.items():
                cart[int(sku_id)] = {
                    # 类型转换
                    'count': int(count),
                    'selected': sku_id in sku_selected
                }
                # 用户未登录
        else:
            # 获取cookie
            cart_cookie = request.COOKIES.get('cart_cookie')

            # 判断cookie是否为空
            if cart_cookie:
                # 解密cookie ,#获取其中得字典数据
                cart = pickle.loads(base64.b64decode(cart_cookie))
            else:
                cart = {}

                # 根据商品id查询出存在商品对象
        skus = SKU.objects.filter(id__in=cart.keys())
        # 再商品对象增加两个属性　购买数量和选中状态
        for sku in skus:
            sku.count = cart[sku.id]['count']
            sku.selected = cart[sku.id]['selected']
            # 传递到定义序列化器中
        ser = SKUSerialziers(skus, many=True)
        # 获取全部对象然后返回 　
        return Response(ser.data)

    def put(self, request):
        # 更改购物车
        # 1、获取前端数据传递商品数据
        data = request.data
        # 前端传递数据　token　商品ｉｄ　数量　选中状态
        ser = CartSerialziers(data=data)
        ser.is_valid()

        sku_id = ser.validated_data['sku_id']
        count = ser.validated_data['count']
        selected = ser.validated_data['selected']
        try:
            # 判断用户是否登录
            user = request.user
        except:
            user = None
        if user is not None:
            conn = get_redis_connection('cart')
            conn.hset('cart_%s' % user.id, sku_id, count)
            if selected:
                conn.sadd('cart_selected_%s' % user.id, sku_id)
            else:
                conn.srem('cart_selected_%s' % user.id, sku_id)
            return Response(ser.data)
        else:
            # 先判断是否有cookie存在
            cart_cookie = request.COOKIES.get('cart_cookie')
            if cart_cookie:
                cart = pickle.loads(base64.b64decode(cart_cookie))
            else:
                # 没有cookie定义一个字典
                cart = {}

            cart[sku_id] = {
                'count': count,
                'selected': selected
            }
            # 设置cookie
            response = Response(ser.data)
            # 将新的字典数据写入cookie
            cart_cookie = base64.b64encode(pickle.dumps(cart)).decode()
            response.set_cookie('cart_cookie', cart_cookie, max_age=60 * 60 * 24 * 7)
            return response

    def delete(self, request):
        # 更改购物车
        # 1、获取前端数据传递商品数据
        data = request.data
        # 前端传递数据　token　商品ｉｄ　数量　选中状态
        ser = CartDeleteSerialziers(data=data)
        ser.is_valid()

        sku_id = ser.validated_data['sku_id']
        try:
            # 判断用户是否登录
            user = request.user
        except:
            user = None
        if user is not None:
            conn = get_redis_connection('cart')
            conn.hdel('cart_%s' % user.id, sku_id)
            conn.srem('cart_selected_%s' % user.id, sku_id)
            return Response(ser.data)
        else:
            # 先判断是否有cookie存在
            cart_cookie = request.COOKIES.get('cart_cookie')

            cart = pickle.loads(base64.b64decode(cart_cookie))
            response = Response('ok')
            if sku_id in cart:
                del cart[sku_id]
            # 设置cookie
            # 将新的字典数据写入cookie
            cart_cookie = base64.b64encode(pickle.dumps(cart)).decode()
            response.set_cookie('cart_cookie', cart_cookie, max_age=60 * 60 * 24 * 7)
            return response


class CartselectionView(APIView):
    def perform_authentication(self, request):
        # 在调用方法之前会获取用户对象，所以重写
        pass
    # 购物车全选
    def put(self, request):
        # 更改购物车
        # 1、获取前端数据传递商品数据
        data = request.data
        # 前端传递数据　token　商品ｉｄ　数量　选中状态
        ser = CartSelectedSerialziers(data=data)
        ser.is_valid()
        selected = ser.validated_data['selected']
        try:
            # 判断用户是否登录
            user = request.user
        except:
            user = None
        if user is not None:
            conn = get_redis_connection('cart')

            sku_id_count = conn.hgetall('cart_%s' % user.id)
            skus  = sku_id_count.keys()
            if selected:
                # 进行拆包
                conn.sadd('cart_selected_%s' % user.id, *skus)

            else:
                conn.srem('cart_selected_%s' % user.id, *skus)
            return Response(ser.data)
        else:
            cart_cookie = request.COOKIES.get('cart_cookie')
            response = Response(ser.data)
            # 先判断是否有cookie存在
            if cart_cookie:
                cart = pickle.loads(base64.b64decode(cart_cookie))

                for sku_id, data_dict in cart.items():
                     data_dict['selected'] = selected
                # 设置cookie
                # 将新的字典数据写入cookie
                cart_cookie = base64.b64encode(pickle.dumps(cart)).decode()
                response.set_cookie('cart_cookie', cart_cookie, max_age=60 * 60 * 24 * 7)
            return response
